package XMLReader;

import java.util.ArrayList;

/**
 *
 * @author moti
 */
public class XMLTree
{
    private ArrayList<XMLEntry> branches;
    private XMLEntry current;
    
    // default constructor
	XMLTree() 
        {
            branches = new ArrayList<XMLEntry>();
            current = null;
	}
        // accessors
        // set current content
        public void content(String value) 
        {
                current.content(value);
        }

        // get current content
        public String content() 
        {
                return current.content();
        }

        // retrieve entry content
        public String[][] get(XMLEntry entry) 
        {
            ArrayList<XMLEntry> children = entry.children();
            String[][] content = new String[children.size()+1][2];
            int i = 0;
            content[i][0] = entry.name();
            content[i][1] = entry.content();
            for (int j = 0; j < children.size(); j++) 
            {
                XMLEntry child = children.get(j);
                content[++i][0] = child.name();
                content[i][1] = child.content();
            }
            return content;
        }

// walk the walk
        // upstream
        public XMLEntry addleaf(XMLEntry leaf) 
        {
            leaf.parent(current);
            if (current == null) branches.add(leaf);
            else current.children().add(leaf);
            return (current = leaf);
        }
        // downstream
        public XMLEntry downstream() 
        {
            return (current = current.parent());
        }

        // walk upstream, pre-order
        public void walk() 
        {
            for (int i = 0; i < branches.size(); i++)
                walk(0, branches.get(i));
        }		

        // recursive pre-order walk
        private void walk(int level, XMLEntry leaf) 
        {
            indent(level, level+" <"+leaf.name()+">\n");
            String content = leaf.content();
            if (content != "") 
                indent(level, "\t"+content+"\n");
            ArrayList<XMLEntry> children = leaf.children();
            if (!children.isEmpty()) 
                for (int i = 0; i < children.size(); i++)
                    walk(level+1, children.get(i)); 
            indent(level, level+" </"+leaf.name()+">\n");
        }

// utilities
        // indent printout
        private void indent(int level, String text) 
        {
            for (int i = 0; i < level; i++) System.out.print("\t"); 
            System.out.print(text);
        }

        private int min(int a, int b) 
        {
            return (a < b) ? a : b;
        }

// find an entry
        // find single tag-value in root
        public XMLEntry find (String tag, String value) 
        {
            return find(new String[] {tag}, new String[] {value});
        }

        // iteratively find tag-value path starting from root
        public XMLEntry find (String[] tag, String[] value) 
        {
            int limit = min(tag.length, value.length);
            XMLEntry entry = null; 
            for (int i = 0; i < limit; i++) 
            {
                ArrayList<XMLEntry> children = (i == 0) ? branches : entry.children();
                entry = find(tag[i], value[i], children); 
                if (entry == null)
                    break;
            }
            return entry;
        }

        // find single tag-value starting from root
        public XMLEntry find (String tag, String value, ArrayList<XMLEntry> root) 
        {
            for (int i = 0; i < root.size(); i++) 
            {
                XMLEntry entry = root.get(i);
                if (tag.equals(entry.name()) && (value.isEmpty() || value.equals(entry.content())))
                    return entry;
            }
            return null;
        }


}

